package me.zixing.java.chapter08.task01;

import java.io.File;
import java.io.RandomAccessFile;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by bingh on 2017/11/10.
 * 使用Nio读写文件工具类
 */
public class Object2FileUtil {
    private static String path = "D://student.txt";

    private static CharsetEncoder encoder;
    private static CharsetDecoder decoder;

    static{
        Charset charset = Charset.forName("UTF-8");
        encoder = charset.newEncoder();
        decoder = charset.newDecoder();
        File file = new File(path);
        if(!file.exists()){
            try{
                file.createNewFile();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    public static void writeObjectToFile(Object object){
        try(
                RandomAccessFile file = new RandomAccessFile(path,"rw");
                FileChannel fileChannel = file.getChannel();

        ){
            CharBuffer charBuffer = CharBuffer.wrap(object.toString());
            ByteBuffer buffer = encoder.encode(charBuffer);
            fileChannel.write(buffer,file.length());
            fileChannel.force(true);

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static <T> List<T> readObjectFromFile(Class<T> clazz){
        if(! PropertiesFillable.class.isAssignableFrom(clazz)){
            throw new IllegalArgumentException(clazz+"必须实现"+PropertiesFillable.class);
        }
        List<T> objects = new ArrayList<>();
        try(
                RandomAccessFile file = new RandomAccessFile(path,"rw");
                FileChannel fileChannel = file.getChannel();

        ){
            ByteBuffer buffer = ByteBuffer.allocateDirect(30);

            StringBuilder builder = new StringBuilder();
            while(fileChannel.read(buffer) != -1){

                buffer.flip();
                CharBuffer charBuffer = decoder.decode(buffer);

                if(buffer.hasRemaining()){
                    buffer.compact();
                }else{
                    buffer.clear();
                }

                while(charBuffer.hasRemaining()){
                    builder.append(charBuffer.get());
                }

            }

            String[] objectStrings = builder.toString().split("\n");
            for (String objectString: objectStrings) {
                T t = clazz.newInstance();
                Method method = clazz.getMethod("fillObjectPropertiesWith",String.class);
                method.invoke(t,objectString);
                objects.add(t);
            }


        }catch (Exception e){
            e.printStackTrace();
        }
        return objects;
    }
}
